package massobjects;

import framework.Force;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import simulation.Assembly;
import simulation.Simulation;


/**
 * Base abstract class that any mass object must extend.
 * 
 * @author David Howdyshell, Zack Hopping
 */
public abstract class BaseMass {
    private static final int MASS_SIZE = 16;
    private Point2D myCenter;
    private Dimension mySize;
    private int myID;

    /**
     * Constructor for this class.
     * 
     * @param id - id number of this mass instance
     * @param x - initial x position
     * @param y - initial y position
     */
    public BaseMass (int id, double x, double y) {
        myID = id;
        setCenter(x, y);
        mySize = new Dimension(MASS_SIZE, MASS_SIZE);
    }

    /**
     * Paints mass object in the applet.
     * 
     * @param pen - pen
     * @param color - color to paint mass
     */
    public void paint (Graphics2D pen, Color color) {
        pen.setColor(color);
        pen.fillOval(getLeft(), getTop(), getSize().width, getSize().height);
    }

    /**
     * Update method must be implemented by child class. Will be different based
     * on mass type.
     * 
     * @param sim - pointer to the instance of the Simulation class
     * @param assem - pointer to assembly of this mass
     * @param dt - delta time since last update
     */
    public abstract void update (Simulation sim, Assembly assem, double dt);

    /**
     * Returns true if match to specified id.
     * 
     * @param id - id to check
     * @return id matches myID
     */
    public boolean match (int id) {
        return myID == id;
    }

    /**
     * Get method for myID.
     * 
     * @return myID
     */
    public int getID () {
        return myID;
    }

    /**
     * Returns mass of current mass object.
     * 
     * @return
     */
    public abstract double getMass ();

    /**
     * Method for child class to implement. How external force affects the mass
     * object.
     * 
     * @param f - force applied to mass
     */
    public abstract void applyForce (Force f);

    /**
     * Returns shape's center.
     */
    public Point2D getCenter () {
        return myCenter;
    }

    /**
     * Resets shape's center.
     * 
     * @param x - horizontal position
     * @param y - vertical position
     */
    public void setCenter (double x, double y) {
        myCenter = new Point2D.Double(x, y);
    }

    /**
     * Returns shape's left-most coordinate.
     */
    public int getLeft () {
        return (int) (getCenter().getX() - getSize().width / 2);
    }

    /**
     * Returns shape's top-most coordinate.
     */
    public int getTop () {
        return (int) (getCenter().getY() - getSize().height / 2);
    }

    /**
     * Returns shape's right-most coordinate.
     */
    public int getRight () {
        return (int) (getCenter().getX() + getSize().width / 2);
    }

    /**
     * Reports shape's bottom-most coordinate.
     * 
     * @return bottom-most coordinate
     */
    public int getBottom () {
        return (int) (getCenter().getY() + getSize().height / 2);
    }

    /**
     * Returns shape's size.
     */
    public Dimension getSize () {
        return mySize;
    }
}
